#ifndef _MISC_MAP_H_
#define _MISC_MAP_H_

#define FX16_ONE	0x1000
#define FX16_HALF	0x0800

#define FX32_ONE	0x1000

typedef s16 fx16;
typedef s32 fx32;

typedef struct
{
    fx32    x;
    fx32    y;
    fx32    z;
}
VecFx32;

typedef union
{
    struct
    {
        fx32    _00, _01, _02;
        fx32    _10, _11, _12;
        fx32    _20, _21, _22;
        fx32    _30, _31, _32;
    };
    fx32    m[4][3];
    fx32    a[12];
}
MtxFx43;

void MI_CpuFill16( void* dest, u16 data, u32 size );

fx16 FX_SinIdx(int idx);
fx16 FX_CosIdx( int idx );



/////////////////////

#define SND_COMMAND_NOBLOCK     0
#define SND_COMMAND_BLOCK     ( 1 << 0 )
#define SND_COMMAND_IMMEDIATE ( 1 << 1 )


#define HW_CPU_CLOCK_ARM7           33513982
#define HW_CPU_CLOCK_ARM9           67027964

#define SND_TIMER_CLOCK ( HW_CPU_CLOCK_ARM7 / 2 )

typedef enum SNDCommandID
{
    SND_COMMAND_START_SEQ,
    SND_COMMAND_STOP_SEQ,
    SND_COMMAND_PREPARE_SEQ,
    SND_COMMAND_START_PREPARED_SEQ,
    SND_COMMAND_PAUSE_SEQ,
    SND_COMMAND_SKIP_SEQ,
    SND_COMMAND_PLAYER_PARAM,
    SND_COMMAND_TRACK_PARAM,
    SND_COMMAND_MUTE_TRACK,
    SND_COMMAND_ALLOCATABLE_CHANNEL,
    SND_COMMAND_PLAYER_LOCAL_VAR,
    SND_COMMAND_PLAYER_GLOBAL_VAR,
    SND_COMMAND_START_TIMER,
    SND_COMMAND_STOP_TIMER,
    SND_COMMAND_SETUP_CHANNEL_PCM,
    SND_COMMAND_SETUP_CHANNEL_PSG,
    SND_COMMAND_SETUP_CHANNEL_NOISE,
    SND_COMMAND_SETUP_CAPTURE,
    SND_COMMAND_SETUP_ALARM,
    SND_COMMAND_CHANNEL_TIMER,
    SND_COMMAND_CHANNEL_VOLUME,
    SND_COMMAND_CHANNEL_PAN,
    SND_COMMAND_SURROUND_DECAY,
    SND_COMMAND_MASTER_VOLUME,
    SND_COMMAND_MASTER_PAN,
    SND_COMMAND_OUTPUT_SELECTOR,
    SND_COMMAND_LOCK_CHANNEL,
    SND_COMMAND_UNLOCK_CHANNEL,
    SND_COMMAND_STOP_UNLOCKED_CHANNEL,
    SND_COMMAND_SHARED_WORK,
    SND_COMMAND_INVALIDATE_SEQ,
    SND_COMMAND_INVALIDATE_BANK,
    SND_COMMAND_INVALIDATE_WAVE,
    SND_COMMAND_READ_DRIVER_INFO
}
SNDCommandID;

/******************************************************************************
	structure definition
 ******************************************************************************/



typedef enum
{
    SND_CHANNEL_0,
    SND_CHANNEL_1,
    SND_CHANNEL_2,
    SND_CHANNEL_3,
    SND_CHANNEL_4,
    SND_CHANNEL_5,
    SND_CHANNEL_6,
    SND_CHANNEL_7,
    SND_CHANNEL_8,
    SND_CHANNEL_9,
    SND_CHANNEL_10,
    SND_CHANNEL_11,
    SND_CHANNEL_12,
    SND_CHANNEL_13,
    SND_CHANNEL_14,
    SND_CHANNEL_15
}
SNDChannelId;

typedef enum
{
    SND_WAVE_FORMAT_PCM8,
    SND_WAVE_FORMAT_PCM16,
    SND_WAVE_FORMAT_ADPCM,
    SND_WAVE_FORMAT_PSG,
    SND_WAVE_FORMAT_NOISE = SND_WAVE_FORMAT_PSG
}
SNDWaveFormat;

typedef enum
{
    SND_CHANNEL_LOOP_MANUAL,
    SND_CHANNEL_LOOP_REPEAT,
    SND_CHANNEL_LOOP_1SHOT
}
SNDChannelLoop;

#define SND_CHANNEL_LOOP_REPAET SND_CHANNEL_LOOP_REPEAT // for compatibility

typedef enum
{
    SND_DUTY_1_8,
    SND_DUTY_2_8,
    SND_DUTY_3_8,
    SND_DUTY_4_8,
    SND_DUTY_5_8,
    SND_DUTY_6_8,
    SND_DUTY_7_8
}
SNDDuty;

typedef enum
{
    SND_CHANNEL_DATASHIFT_NONE,
    SND_CHANNEL_DATASHIFT_1BIT,
    SND_CHANNEL_DATASHIFT_2BIT,
    SND_CHANNEL_DATASHIFT_4BIT
}
SNDChannelDataShift;

typedef struct SNDCommand
{
    struct SNDCommand *next;
    SNDCommandID id;
    u32     arg[4];
}
SNDCommand;


void SND_StopTimer(u32 chBitMask,u32 capBitMask,u32 alarmBitMask,u32 flags );
void SND_StartTimer(u32 chBitMask,u32 capBitMask,u32 alarmBitMask,u32 flags );
const SNDCommand* SND_RecvCommandReply( u32 flags );
BOOL SND_FlushCommand( u32 flags );
void SND_SetupChannelPcm(int chNo,SNDWaveFormat format,const void* dataAddr,SNDChannelLoop loop,int loopStart,int dataLen,int volume,SNDChannelDataShift shift,int timer,int pan );
void SND_SetChannelVolume(u32 chBitMask,int volume,SNDChannelDataShift shift );
#endif //_MISC_MAP_H_